package com.tanhua.server.service;

import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.commons.templates.OssTemplate;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.Comment;
import com.tanhua.domain.mongo.FollowUser;
import com.tanhua.domain.mongo.Video;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.domain.vo.VideoVo;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.VideoApi;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;

@Service
public class VideoService {

    @Reference
    private VideoApi videoApi;

    @Reference
    private UserInfoApi userInfoApi;

    @Autowired
    private OssTemplate ossTemplate;

    @Autowired
    private FastFileStorageClient fastFileStorageClient;

    @Autowired
    private FdfsWebServer fdfsWebServer;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private VideoMQService videoMQService;

    /**
     * 接口名称：小视频列表
     */
    public PageResult queryVideoList(Integer page, Integer pagesize) {

        System.out.println("从数据库查询");

        // 1.查询redis的推荐数据
        PageResult pageResult = findByRecommend(UserHolder.getUserId(), page, pagesize);

        if (pageResult == null) {
            // 1.1 如果redis数据为空，再调用服务提供者api分页查询小视频列表
            pageResult = videoApi.queryVideoList(page, pagesize);
        }

        // 获取当前页的数据
        List<Video> videoList = (List<Video>) pageResult.getItems();

        // 2.封装返回结果
        List<VideoVo> voList = new ArrayList<>();
        if (videoList != null) {
            for (Video video : videoList) {
                // 2.1 创建vo
                VideoVo vo = new VideoVo();

                // 2.2 封装数据
                BeanUtils.copyProperties(video, vo);

                // 查询用户详情
                UserInfo userInfo = userInfoApi.findById(video.getUserId());
                if (userInfo != null) {
                    BeanUtils.copyProperties(userInfo, vo);
                }

                vo.setId(video.getId().toString());
                vo.setCover(video.getPicUrl());
                vo.setSignature(video.getText());
                vo.setHasLiked(0);

                // 获取存在redis的关注标记
                String key = "followUser_" + UserHolder.getUserId() + "_" + video.getUserId();
                if (redisTemplate.hasKey(key)) {
                    // 已关注用户
                    vo.setHasFocus(1);
                } else {
                    vo.setHasFocus(0);
                }

                // 获取存在redis的点赞标记
                String videoLikeKey = "video_like_comment_" + UserHolder.getUserId() + "_" + video.getId();
                if (redisTemplate.hasKey(videoLikeKey)) {
                    // 以点赞
                    vo.setHasLiked(1);
                }else {
                    vo.setHasLiked(0);
                }

                // 2.3 添加vo到集合
                voList.add(vo);
            }
        }
        // 3.重新设置items的值
        pageResult.setItems(voList);

        return pageResult;
    }

    /**
     * 查询redis中的推荐数据
     *
     * @param userId
     * @param page
     * @param pagesize
     * @return
     */
    private PageResult findByRecommend(Long userId, Integer page, Integer pagesize) {
        // 1.拼接key
        String key = "QUANZI_VIDEO_RECOMMEND_" + userId;

        // 2.根据key查询redis
        String value = redisTemplate.opsForValue().get(key);

        if (StringUtils.isEmpty(value)) {
            return null;
        }

        // 3.将value转为数组
        String[] vids = value.split(",");

        // 4.将数组转为list集合
        List<Long> vidList = new ArrayList<>();
        for (String vid : vids) {
            vidList.add(Long.valueOf(vid));
        }

        // 5.调用服务提供者分页查询小视频列表
        PageResult pageResult = videoApi.findByIds(vidList, page, pagesize);

        return pageResult;
    }

    /**
     * 接口名称：视频上传
     */
    @CacheEvict(value = "videoList", allEntries = true)
    public ResponseEntity<Object> uploadVideos(MultipartFile videoThumbnail, MultipartFile videoFile) throws Exception {

        // 1.上传封面文件到阿里云oss
        String picUrl = ossTemplate.upload(videoThumbnail.getOriginalFilename(), videoThumbnail.getInputStream());

        // 2.上传小视频到fastDFS
        // 2.1 获取文件名，假设文件名叫test.avi
        String fileName = videoFile.getOriginalFilename();
        // 2.2 获取文件扩展名，获取上例中的avi
        String extName = fileName.substring(fileName.lastIndexOf(".") + 1);
        StorePath storePath = fastFileStorageClient.uploadFile(videoFile.getInputStream(), videoFile.getSize(), extName, null);
        // 2.3 封装完整的小视频访问url
        String videoUrl = fdfsWebServer.getWebServerUrl() + storePath.getFullPath();

        // 3.创建小视频对象
        Video video = new Video();
        video.setId(ObjectId.get()); // 提前设置id
        video.setUserId(UserHolder.getUserId());
        video.setText("左手右手一个慢动作");
        video.setPicUrl(picUrl);
        video.setVideoUrl(videoUrl);
        video.setCreated(System.currentTimeMillis());

        videoApi.save(video);

        // 【发送评分消息到MQ】
        videoMQService.sendMsg(video.getId().toString(), 1);

        return ResponseEntity.ok(null);
    }

    /**
     * 接口名称：视频用户关注
     */
    public ResponseEntity<Object> followUser(Long uid) {
        // 1.创建followUser对象
        FollowUser followUser = new FollowUser();
        followUser.setCreated(System.currentTimeMillis());
        followUser.setUserId(UserHolder.getUserId());
        followUser.setFollowUserId(uid);

        // 2.调用服务提供者api保存关注数据
        videoApi.followUser(followUser);

        // 3.存入用户关注的标记
        String key = "followUser_" + UserHolder.getUserId() + "_" + uid;
        redisTemplate.opsForValue().set(key, "xxx");

        return ResponseEntity.ok(null);
    }

    /**
     * 接口名称：视频用户关注 - 取消
     */
    public ResponseEntity<Object> unfollowUser(Long uid) {
        // 1.调用服务提供者api删除关注数据
        videoApi.unfollowUser(UserHolder.getUserId(), uid);

        // 2.删除redis中的关注标记
        String key = "followUser_" + UserHolder.getUserId() + "_" + uid;
        redisTemplate.delete(key);

        return ResponseEntity.ok(null);
    }



}
